package com.iot08.api.service;

import com.alibaba.fastjson.JSONObject;
import com.iot08.api.config.redis.RedisClusterService;
import com.iot08.api.response.WechatContactResp;
import com.iot08.api.service.supplement.KafkaService;
import com.iot08.api.utils.StringTool;
import com.iot08.api.utils.buckettool.BaseBucketTool;
import com.iot08.api.vo.request.DeviceWechatContactDelReqVO;
import com.iot08.api.vo.request.DeviceWechatContactQueryReqVO;
import com.iot08.api.vo.request.DeviceWechatContactUpdateReqVO;
import com.iot08.api.vo.request.ImeiParamReqBodyFormVO;
import com.iot08.common.constant.ConstCacheField;
import com.iot08.common.constant.ConstKafka;
import com.iot08.common.entity.app.Account;
import com.iot08.common.entity.app.ChatGroup;
import com.iot08.common.entity.app.Device;
import com.iot08.common.entity.app.WechatContact;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.response.ResponseEnum;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author cwj
 * @description
 * @date 2025/6/24 15:08
 **/
@Slf4j
@Service
public class WechatContactService extends BaseService<WechatContact> {

    @Resource
    private RedisClusterService redisClusterService;

    @Resource
    private KafkaService kafkaService;

    @Resource
    private BaseBucketTool baseBucketTool;

    @Resource
    @Lazy
    private AccountService accountService;

    @Resource
    private ChatGroupService chatGroupService;

    @Resource
    @Lazy
    private DeviceService deviceService;


    
    /**
     * @description 查询微聊的联系人信息
     * @author cwj
     * @param [imei, phone]
     * @return com.iot08.common.entity.app.WechatContact
     * @date @time 2025/6/24 15:13
     **/
    public WechatContact queryByImePhone(String imei,String phone){
        Query query = new Query(Criteria.where("imei").is(imei).and("phone").is(phone)).limit(1);
        return this.findOne(query);
    }

    /**
     * @description 查询微聊联系人的信息
     * @author cwj
     * @param [imei, openid]
     * @return com.iot08.common.entity.app.WechatContact
     * @date @time 2025/6/25 17:07
     **/
    public WechatContact queryByImeOpenId(String imei,String openid){
        Query query = new Query(Criteria.where("imei").is(imei).and("openid").is(openid)).limit(1);
        return this.findOne(query);
    }


    /**
     * @description 保存或更新微聊联系人数据
     * @author cwj
     * @param [imei, phone, name, avator]
     * @return void
     * @date @time 2025/6/24 15:48
     **/
    public void saveOrUpdateWechatContact(String imei,String phone,String openid, String groupid,String name,String avator){
        Date date = new Date();
        WechatContact wechatContact = this.queryByImeOpenId(imei,openid);
        if(ObjectUtils.isEmpty(wechatContact)) {
            wechatContact = new WechatContact();
            wechatContact.setImei(imei);
            wechatContact.setPhone(phone);
            wechatContact.setOpenid(openid);
            wechatContact.setGroupid(groupid);
            wechatContact.setName(name);
            wechatContact.setAvator(avator);
            wechatContact.setCreateTime(date.getTime()/1000);
            wechatContact.setUpdateTime(date.getTime()/1000);
            this.save(wechatContact);
        } else {
            Update update = new Update();
            if(StringUtils.isNotEmpty(openid)) {
                update.set("openid",openid);
            }
            if(StringUtils.isNotEmpty(groupid)) {
                update.set("groupid",groupid);
            }
            if(StringUtils.isNotEmpty(name)) {
                update.set("name",name);
            }
            if(StringUtils.isNotEmpty(avator)) {
                update.set("avator",avator);
            }
            update.set("updateTime",date.getTime()/1000);
            this.updateById(new ObjectId(wechatContact.getId()),update);
        }
    }
    
    /**
     * @description 清除设备绑定的微聊联系人信息
     * @author cwj
     * @param [imei]
     * @return void
     * @date @time 2025/6/24 16:30
     **/
    public void delByImei(String imei){
        Query query = new Query(Criteria.where("imei").is(imei));
        mongoTemplate.remove(query,WechatContact.class);
    }


    /**
     * @description 更新设备的微聊联系人
     * @author cwj
     * @param [imei, vo, image]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/6/24 17:38
     **/
    public ResponseMap updateWechatContact(String imei,DeviceWechatContactUpdateReqVO vo, MultipartFile image) throws IOException {
        //检查设备是否在线，不在线不能下发
        String onlineStatus = redisClusterService.hget(imei, ConstCacheField.ONLINE_STATUS);
        if (!"1".equals(onlineStatus)) {
            return ResponseMap.fail(ResponseEnum.STATUS5001.getCode(), ResponseEnum.STATUS5001.getMsg());
        }
        Device device = deviceService.findById(imei);
        if (device == null) {
            log.error("Device is null. _id={}", imei);
            return ResponseMap.fail(ResponseEnum.STATUS2001.getCode(), ResponseEnum.STATUS2001.getMsg(), imei);
        }
        //检查操作用户的账户信息，检查删除微聊联系人是否为本人，如果不是本人则只有管理员才有权限删除
        Account account = accountService.findById(vo.getOpenid());
        if(ObjectUtils.isEmpty(account)) {
            return ResponseMap.fail(ResponseEnum.STATUS2000.getCode(), "操作用户已注销，无法操作");
        }
        //获得操作用户身份
        String identity = getOptIdentity(imei, account.getDeviceMap());
        //是管理员或者更新自己的微聊记录是允许的
        if ("admin".equals(identity) || vo.getUpdatedOpenid().equals(account.getId())) {
            //查询当前微聊联系人记录
            WechatContact wechatContact = this.queryByImeOpenId(imei, vo.getUpdatedOpenid());
            if (ObjectUtils.isEmpty(wechatContact)) {
                log.error("设备：{}的微聊联系人不存在！", imei);
                return ResponseMap.fail(ResponseEnum.STATUS2002.getCode(), "微聊联系人不存在，请联系管理员解决", imei);
            }
            Update update = new Update();
            JSONObject kafkaJson = new JSONObject();
            update.set("name", vo.getName());
            kafkaJson.put("name", vo.getName());
            kafkaJson.put("phone", wechatContact.getPhone());
            kafkaService.emitDeviceDemand(imei, ConstKafka.DEVICE_TYPE_UPDATE_NEW_CONTACT_NAME, kafkaJson, vo.getOpenid());
            this.updateById(new ObjectId(wechatContact.getId()), update);
        }
        return ResponseMap.success();
    }


    /**
     * @description 更新微聊联系人的名字
     * @author cwj
     * @param [imei, openid, name]
     * @return void
     * @date @time 2025/7/8 17:18
     **/
    public void updateWechatContactName(String imei,String openid,String name){
        WechatContact wechatContact = this.queryByImeOpenId(imei, openid);
        if (ObjectUtils.isEmpty(wechatContact)) {
            log.error("设备：{}的微聊联系人不存在！", imei);
            return;
        }
        Update update = new Update();
        update.set("name", name);
        this.updateById(new ObjectId(wechatContact.getId()), update);
    }
    

    /**
     * @description 删除设备的微聊联系人
     * @author cwj
     * @param [imei, vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/6/24 18:21
     **/
    public ResponseMap deleteWechatContact(String imei,DeviceWechatContactDelReqVO vo) {
        //检查设备是否在线，不在线不能下发
        String onlineStatus = redisClusterService.hget(imei, ConstCacheField.ONLINE_STATUS);
        if (!"1".equals(onlineStatus)) {
            return ResponseMap.fail(ResponseEnum.STATUS5001.getCode(), ResponseEnum.STATUS5001.getMsg());
        }
        Device device = deviceService.findById(imei);
        if (device == null) {
            log.error("Device is null. _id={}", imei);
            return ResponseMap.fail(ResponseEnum.STATUS2001.getCode(), ResponseEnum.STATUS2001.getMsg(), imei);
        }
        //检查操作用户的账户信息，检查删除微聊联系人是否为本人，如果不是本人则只有管理员才有权限删除
        Account account = accountService.findById(vo.getOpenid());
        if(ObjectUtils.isEmpty(account)) {
            return ResponseMap.fail(ResponseEnum.STATUS2000.getCode(), "操作用户已注销，无法操作");
        }
        //获得操作用户身份
        String identity = getOptIdentity(imei, account.getDeviceMap());
        //是管理员或者删除自己的微聊记录是允许的
        if ("admin".equals(identity) || vo.getDeletedOpenid().equals(account.getId())) {
            //走解绑逻辑
            ImeiParamReqBodyFormVO bodyFormVO = new ImeiParamReqBodyFormVO();
            bodyFormVO.setImei(imei);
            bodyFormVO.setIsForceUnbind(1);
            bodyFormVO.setOpenid(vo.getOpenid());
            //解除设备和用户的绑定关系（解绑）
            return accountService.delUserRelatedDevice(bodyFormVO,vo.getDeletedOpenid());
        } else {
            return ResponseMap.fail(ResponseEnum.STATUS2002.getCode(), "用户没有权限删除设备的其它联系人");
        }
    }


    /**
     * @description 获取用户身份信息
     * @author cwj
     * @param [imei, deviceMap]
     * @return java.lang.String
     * @date @time 2025/6/26 8:47
     **/
    private String getOptIdentity(String imei, Map<String, Map<String, Object>> deviceMap) {
        String identity = null;
        if(deviceMap != null){
            for (String item : deviceMap.keySet()) {
                if (imei.equals(item)) {
                    identity = deviceMap.get(item).get("identity").toString();
                }
            }
        }
        return identity;
    }

    /**
     * @description 查询设备微聊群聊组中的联系人
     * @author cwj
     * @param [imei, device, vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/6/25 14:21
     **/
    public ResponseMap queryWechatContact(String imei, DeviceWechatContactQueryReqVO vo) {
        Device device = deviceService.findById(imei);
        if (device == null) {
            log.error("Device is null. _id={}", imei);
            return ResponseMap.fail(ResponseEnum.STATUS2001.getCode(), ResponseEnum.STATUS2001.getMsg(), imei);
        }
        ChatGroup chatGroup = chatGroupService.findById(new ObjectId(vo.getGroupId()));
        if(ObjectUtils.isEmpty(chatGroup)) {
            log.error("设备群聊组为空，设备为：{}", imei);
            return ResponseMap.fail(ResponseEnum.STATUS2002.getCode(), "设备群聊分组不群在");
        }
        //查询设备群聊组成员信息
        Query query = new Query(Criteria.where("imei").is(imei).and("groupid").is(vo.getGroupId()));
        //查询微聊群聊的联系人信息
        List<WechatContactResp> wechatContactList = mongoTemplate.find(query,WechatContactResp.class,"wechat_contact");
        Map<String,Map<String,Object>> userMap = device.getUserMap();
        for (Map.Entry<String, Map<String,Object>> entry : userMap.entrySet()) {
            Map<String,Object> value = entry.getValue();
            for(WechatContactResp w:wechatContactList) {
                if(w.getOpenid().equals(entry.getKey()) && MapUtils.isNotEmpty(value)) {
                    if(ObjectUtils.isNotEmpty(value.get("identity"))) {
                        w.setIdentity(value.get("identity").toString());
                    } else {
                        w.setIdentity("member");
                    }
                }
            }
        }
        ResponseMap res = ResponseMap.success();
        res.put("wechatContactList",wechatContactList);
        return res;
    }
    

    /**
     * @description 更新用户对应的微聊信息的头像信息
     * @author cwj
     * @param [deviceMap, openid, avator]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/6/25 16:07
     **/
    public void updateUserWechatContact(Map<String, Map<String, Object>> deviceMap,String openid,String avator) {
        if(ObjectUtils.isNotEmpty(deviceMap) && StringUtils.isNotEmpty(avator)) {
            List<String> imeis = new ArrayList<>();
            for (Map.Entry<String, Map<String, Object>> entry : deviceMap.entrySet()) {
                imeis.add(entry.getKey());
            }
            if(!CollectionUtils.isEmpty(imeis)) {
                List<Device> devices = deviceService.listByIds(imeis);
                if(!CollectionUtils.isEmpty(devices)) {
                    Query query = new Query(Criteria.where("openid").is(openid).and("imei").in(imeis));
                    List<WechatContact> wechatContactList = this.find(query);
                    if(!CollectionUtils.isEmpty(wechatContactList)) {
                        devices.forEach(d->{
                            //设备是新版微聊协议则更新微聊联系人的头像
                            if(ObjectUtils.isNotEmpty(d.getIsNewWechatProtocol()) && d.getIsNewWechatProtocol().equals(1)) {
                                wechatContactList.forEach(w->{
                                    //RTOS设备暂时无法成功设置头像
                                    if(w.getImei().equals(d.getId()) && w.getOpenid().equals(openid)) {
                                        //更新头像信息并下发指令
                                        Update update = new Update();
                                        if(!avator.contains(baseBucketTool.getDOMAIN())){
                                            update.set("avator",baseBucketTool.getDOMAIN() + avator);
                                        } else {
                                            update.set("avator", avator);
                                        }
                                        update.set("updateTime",new Date().getTime()/1000);
                                        this.updateById(new ObjectId(w.getId()),update);
                                        //RTOS设备不下发图片指令
                                        if(!"ASR".equals(d.getPlatform())) {
                                            JSONObject kafkaJson = new JSONObject();
                                            //发送更新微聊头像的指令
                                            kafkaJson.put("phone", w.getPhone());
                                            kafkaJson.put("avator", avator);
                                            //发送修改微聊联系人图像的指令
                                            kafkaService.emitDeviceDemand(d.getId(), ConstKafka.DEVICE_TYPE_UPDATE_NEW_CONTACT_AVATOR, kafkaJson, openid);
                                        }
                                    }
                                });
                            }
                        });
                    }
                }
            }
        }
    }
}
